class Snake {
    // 表示蛇头的元素
    head: HTMLElement;
    // 蛇的身体， 包括蛇头
    bodies: HTMLCollection;
    element: HTMLElement;
    constructor() {
        this.element = document.getElementById("snake")!;
        this.head = document.querySelector("#snake > div") as HTMLElement;
        this.bodies = this.element.getElementsByTagName("div");
    }

    // 获取蛇的坐标 蛇头的坐标
    get X() {
        return this.head.offsetLeft;
    }
    get Y() {
        return this.head.offsetTop;
    }
    // 设置蛇头的坐标
    set X(value) {
        if (this.X == value) {
            return;
        }
        // 判断X值的合理范围
        if (value < 0 || value >= 290) {
            // 说明蛇撞墙了
            throw new Error("蛇撞墙了, Game Over!!!");
        }
        // 修改X，是在修改水平坐标，蛇在向左移动是，不能向右掉头，反之亦然
        // 当蛇头的坐标和第二节坐标是一致，表示掉头
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
           // 发生了掉头 让蛇走反方向继续
           if (value > this.X) {
               // value > X 蛇向右边走，此时发生掉头，应该使得蛇向左走
               value = this.X -10;
           } else {
               value = this.X + 10;
           }
        }
        // 移动身体
        this.moveBody();
        this.head.style.left = value + 'px';
        this.checkHeadBody();
    }
    set Y(value) {
        if (this.Y === value) {
            return;
        }
        if (value < 0 || value >= 290) {
            // 说明蛇撞墙了
            throw new Error("蛇撞墙了, Game Over!!!");
        }
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
            // 发生了掉头 让蛇走反方向继续
            if (value > this.Y) {
                // value > X 蛇向右边走，此时发生掉头，应该使得蛇向左走
                value = this.Y -10;
            } else {
                value = this.Y + 10;
            }
         }
        // 移动身体
        this.moveBody();
        this.head.style.top = value + 'px';
        this.checkHeadBody();
    }

    // 蛇增加身体的方法
    addBody() {
        // 在element中添加一个div
        this.element.insertAdjacentHTML("beforeend", "<div></div>");
    }
    //  添加一个蛇身体移动的方法
    moveBody() {
        // 将蛇后面的每一节设置为前边身体的位置
        // 比如第四节蛇身 = 第三节蛇身
        for(let i = this.bodies.length - 1; i > 0; i--) {
            console.log(this.bodies[i])
            let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
            let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

            // 将值设置在当前身体上
            (this.bodies[i] as HTMLElement).style.left = X + "px";
            (this.bodies[i] as HTMLElement). style.top = Y +"px";
        }
    }
    checkHeadBody() {
        // 获取所有的身体 检查其是否和蛇头的坐标发生重叠
        for(let i = 1; i < this.bodies.length; i++) {
            let bd = this.bodies[i] as HTMLElement;
            if (this.head.offsetLeft === bd.offsetLeft && this.head.offsetTop === bd.offsetTop) {
                throw new Error("蛇头撞到自己啦")
            }
        }
    }
}
export default Snake;